home *** CD-ROM | disk | FTP | other *** search
/ AOL File Library: 2,801 to 2,900 / aol-file-protocol-4400-2801-to-2900.zip / AOLDLs / C++ Files Library / Acere (Card Game) / AcereÄ.sit / Acereƒ / CardWell.cp < prev    next >
Text File  |  1994-08-25  |  9KB  |  357 lines

  1. // ===========================================================================
  2. //    CardWell.cp                        ⌐1993 Metrowerks Inc. All rights reserved.
  3. // ===========================================================================
  4. //
  5. //    Class for an object that can draw itself and respond to mouse clicks
  6.  
  7. #ifdef PowerPlant_PCH
  8. #include PowerPlant_PCH
  9. #endif
  10.  
  11. #include "CardWell.h"
  12. #include "CardDeck.h"
  13. #include "WellDeck.h"
  14. #include "CTextDoc.h"
  15. #include "AcereApp.h"
  16. #include <LView.h>
  17. #include <LStream.h>
  18. #include <PP_Messages.h>
  19. #include <UDrawingState.h>
  20.  
  21. extern CTextDoc    *theDoc;
  22.  
  23. // ---------------------------------------------------------------------------
  24. //        Ñ CreatePaneStream [static]
  25. // ---------------------------------------------------------------------------
  26. //    Return a new Pane object initialized using data from a Stream
  27.  
  28. CardWell*
  29. CardWell::CreateCardWell(
  30.     LStream    *inStream)
  31. {
  32.     return (new CardWell(inStream));
  33. }
  34.  
  35.  
  36. // ---------------------------------------------------------------------------
  37. //        Ñ CardWell()
  38. // ---------------------------------------------------------------------------
  39. //    Default Constructor
  40.  
  41. CardWell::CardWell()
  42. {
  43.     mPaneID = 0;
  44.     mFrameSize.width = mFrameSize.height = 0;
  45.     mFrameLocation.h = mFrameLocation.v = 0;
  46.     mUserCon = 0;
  47.     
  48.     mFrameBinding.left =
  49.         mFrameBinding.top =
  50.         mFrameBinding.right =
  51.         mFrameBinding.bottom = false;
  52.     
  53.     mVisible = mActive = mEnabled = triState_Latent;
  54.  
  55.     mSuperView = nil;
  56.     
  57. }
  58.  
  59.  
  60. // ---------------------------------------------------------------------------
  61. //        Ñ CardWell(const CardWell&)
  62. // ---------------------------------------------------------------------------
  63. //    Copy Constructor
  64.  
  65. CardWell::CardWell(
  66.     const CardWell    &inOriginal)
  67. {
  68.                                     // Copy members of Original
  69.     mPaneID = inOriginal.mPaneID;
  70.     mFrameSize = inOriginal.mFrameSize;
  71.     mFrameLocation = inOriginal.mFrameLocation;
  72.     mFrameBinding = inOriginal.mFrameBinding;
  73.     mUserCon = inOriginal.mUserCon;
  74.     
  75.     mSuperView = nil;                // Copy is not inside any View
  76.     
  77.                                     // Pane properties. If Original has
  78.                                     //   property ON, Copy is Latent.
  79.     mVisible = inOriginal.mVisible;
  80.     if (mVisible == triState_On) {
  81.         mVisible = triState_Latent;
  82.     }
  83.  
  84.     mActive = inOriginal.mActive;
  85.     if (mActive == triState_On) {
  86.         mActive = triState_Latent;
  87.     }
  88.  
  89.     mEnabled = inOriginal.mEnabled;
  90.     if (mEnabled == triState_On) {
  91.         mEnabled = triState_Latent;
  92.     }
  93.  
  94. }
  95.  
  96.  
  97. // ---------------------------------------------------------------------------
  98. //        Ñ CardWell(SPaneInfo&)
  99. // ---------------------------------------------------------------------------
  100. //    Construct Pane from data in a struct
  101.  
  102. CardWell::CardWell(
  103.     const SPaneInfo    &inPaneInfo)
  104. {
  105.     InitPane(inPaneInfo);
  106. }
  107.  
  108.  
  109. // ---------------------------------------------------------------------------
  110. //        Ñ CardWell(LStream*)
  111. // ---------------------------------------------------------------------------
  112. //    Construct Pane from data in a Stream
  113.  
  114. CardWell::CardWell(
  115.     LStream    *inStream)
  116. {
  117.     SPaneInfo    thePaneInfo;
  118.     inStream->ReadData(&thePaneInfo, sizeof(SPaneInfo));
  119.     InitPane(thePaneInfo);
  120. }
  121.  
  122.  
  123. // ---------------------------------------------------------------------------
  124. //        Ñ InitPane
  125. // ---------------------------------------------------------------------------
  126. //    Initialize Pane from data in a struct
  127.  
  128. void
  129. CardWell::InitPane(
  130.     const SPaneInfo    &inPaneInfo)
  131. {
  132.         short    whichCard;
  133.     
  134.     mPaneID = inPaneInfo.paneID;
  135.     mFrameSize.width = inPaneInfo.width;
  136.     mFrameSize.height = inPaneInfo.height;
  137.     mUserCon = inPaneInfo.userCon;
  138.     
  139.     mVisible = triState_Off;
  140.     if (inPaneInfo.visible) {
  141.         mVisible = triState_Latent;
  142.     }
  143.  
  144.     mActive = triState_Latent;
  145.  
  146.     mEnabled = triState_Off;
  147.     if (inPaneInfo.enabled) {
  148.         mEnabled = triState_Latent;
  149.     }
  150.     
  151.     mFrameBinding = inPaneInfo.bindings;
  152.     
  153.     mSuperView = nil;
  154.     
  155.     LView    *theSuperView = inPaneInfo.superView;
  156.     if (theSuperView == Default_SuperView) {
  157.         theSuperView = GetDefaultView();
  158.     }
  159.     PutInside(theSuperView);
  160.     if (theSuperView != nil) {
  161.         PlaceInSuperImageAt(inPaneInfo.left, inPaneInfo.top, false);
  162.         Boolean    expandHoriz = (inPaneInfo.width < 0);
  163.         Boolean    expandVert = (inPaneInfo.height < 0);
  164.         if (expandHoriz || expandVert) {
  165.             theSuperView->ExpandSubPane(this, expandHoriz, expandVert);
  166.         }
  167.     }
  168.     
  169.     whichCard = theDeck->GetNextCardPosition();
  170.     theDeck->GetCardInfo(whichCard, &itsCard);
  171.     itsCard.card = kNoCard;
  172. }
  173.  
  174.  
  175. // ---------------------------------------------------------------------------
  176. //        Ñ ~CardWell
  177. // ---------------------------------------------------------------------------
  178. //    Destructor
  179.  
  180. CardWell::~CardWell()
  181. {
  182.     PutInside(nil);
  183.     
  184.     if (sLastPaneClicked == this) {
  185.         sLastPaneClicked = nil;
  186.     }
  187. }
  188.  
  189.  
  190. // ---------------------------------------------------------------------------
  191. //        Ñ Draw
  192. // ---------------------------------------------------------------------------
  193. //    Try to draw contents of a Pane
  194. //
  195. //    inSuperDrawRgnH specifies, in Port coordinates, the portion of the
  196. //    Pane's SuperView that needs to be drawn. Specify nil to bypass
  197. //    the intersection test.
  198. //    
  199. //    This is a wrapper function which calls DrawSelf if it is proper for
  200. //    the Pane to draw. This means that:
  201. //        > Pane's Visible property is on
  202. //        > Pane can be focused
  203. //        > Pane's Frame is in QuickDraw space
  204. //        > Pane's Frame intersects inSuperDrawRgnH
  205.  
  206. void    CardWell::Draw(RgnHandle    inSuperDrawRgnH)
  207. {
  208.     Rect    frame;
  209.     if ( IsVisible()  &&
  210.          FocusDraw()  &&
  211.          CalcPortFrameRect(frame)  &&
  212.          ((inSuperDrawRgnH == nil) || RectInRgn(&frame, inSuperDrawRgnH)) )
  213.     {
  214.         if (itsCard.card == kNoCard)
  215.         {
  216.             frame.bottom = frame.top + 90;
  217.             EraseRect(&frame);
  218.             FrameRoundRect(&frame, 20, 20);
  219.         }
  220.         else
  221.         {
  222.             theDeck->DrawCard(&itsCard, frame);
  223. //            FrameRoundRect(&frame, 20, 20);
  224.         }
  225.     }
  226. }
  227.  
  228. Boolean    CardWell::CanRemove(void)            //    can we remove cards from this pile?
  229. {
  230.     return (true);
  231. }
  232.  
  233. Boolean    CardWell::CanDrop(CardStruct *draggedCard)
  234. {
  235.     if (itsCard.card == kNoCard)
  236.         return (CanDropOnEmptySlot(draggedCard));
  237.         
  238.     else
  239.         return (CanDropOnSlot(draggedCard));
  240. }
  241.  
  242. Boolean    CardWell::CanDropOnEmptySlot(CardStruct *draggedCard)
  243. {
  244.     //    this will be overridden by most subclasses, which is why it's separate
  245.     //    default behavior is that ANY card can be dropped on an empty slot
  246.     
  247.     return (true);
  248. }
  249.  
  250. Boolean    CardWell::CanDropOnSlot(CardStruct *draggedCard)
  251. {
  252.     //    this will be overridden by most subclasses.
  253.     //    default behavior is that no card can be dropped on any card.
  254.     
  255.     return (false);
  256. }
  257.     
  258.  
  259. void    CardWell::AddCardToWell(CardWell *whichWell, CardStruct *whichCard)
  260. {
  261.     whichCard->itsOwner = this;
  262.     itsCard = *whichCard;
  263. }
  264.  
  265.  
  266. void    CardWell::RemoveCardFromWell(CardWell *whichWell, CardStruct *whichCard)
  267. {
  268.     itsCard.card = kNoCard;
  269. }
  270.  
  271.  
  272. void    CardWell::Click(SMouseDownEvent &inMouseDown)
  273. {
  274.         CardWell    *firstOwner, *secondOwner;
  275.         
  276.         
  277.     LPane::Click(inMouseDown);
  278.     
  279.     if (sClickCount > 1)            //    user double-clicked
  280.     {
  281.         short    j;
  282.         
  283.         for (j=0; j < 4; j++)
  284.         {
  285.             secondOwner = theDoc->theDeckWells[j]->itsCard.itsOwner;
  286.  
  287.             if (secondOwner->CanDrop(&(theDoc->firstCard)))
  288.             {
  289.                 firstOwner = theDoc->firstCard.itsOwner;
  290.  
  291.                 theDoc->firstCard.itsOwner->RemoveCardFromWell(theDoc->firstCard.itsOwner, 
  292.                     &theDoc->firstCard);
  293.  
  294.                 theDoc->theDeckWells[j]->itsCard.itsOwner->AddCardToWell(
  295.                         theDoc->theDeckWells[j]->itsCard.itsOwner, 
  296.                         &theDoc->firstCard);
  297.                 
  298.                 theDoc->firstCard.card = theDoc->secondCard.card = kNoCard;
  299.                 
  300.                 firstOwner->Draw(nil);
  301.                 secondOwner->Draw(nil);
  302.                 
  303.                 return;
  304.             }
  305.             
  306.         }
  307.         
  308.     }
  309.     
  310.     if (theDoc->firstCard.card == kNoCard)
  311.     {
  312.         if (CanRemove())
  313.             theDoc->firstCard = itsCard;
  314.         else
  315.             SysBeep(3);
  316.     }
  317.     else if ((theDoc->firstCard.card == itsCard.card) && 
  318.                     (theDoc->firstCard.suit == itsCard.suit))
  319.         theDoc->firstCard.card = kNoCard;            //    toggle selection
  320.     else
  321.     {
  322.         theDoc->secondCard = itsCard;
  323.     
  324.         //    this is a little tricky -- we need to call the subclass's method
  325.         
  326.         if (theDoc->secondCard.itsOwner->CanDrop(&(theDoc->firstCard)))
  327.         {
  328.             //    we can drag
  329.             
  330.             //    first we remove the card from its old slot
  331.             
  332.             firstOwner = theDoc->firstCard.itsOwner;
  333.             secondOwner = theDoc->secondCard.itsOwner;
  334.             
  335.             theDoc->firstCard.itsOwner->RemoveCardFromWell(theDoc->firstCard.itsOwner, 
  336.                     &theDoc->firstCard);
  337.                     
  338.             //    then we add it to the second slot
  339.             
  340.             theDoc->secondCard.itsOwner->AddCardToWell(theDoc->secondCard.itsOwner, 
  341.                     &theDoc->firstCard);
  342.             
  343.             theDoc->firstCard.card = theDoc->secondCard.card = kNoCard;
  344.             
  345.             firstOwner->Draw(nil);
  346.             secondOwner->Draw(nil);
  347.             
  348.         }
  349.         else                //    we couldn't drop the card
  350.         {
  351.             theDoc->secondCard.card = kNoCard;
  352.             SysBeep(3);
  353.         }
  354.     }
  355. }
  356.  
  357.